using WCell.Constants;
using WCell.Constants.NPCs;
using WCell.RealmServer.NPCs;
using WCell.Util;
using WCell.Util.Data;
using System.Collections.Generic;
using WCell.RealmServer.Content;

namespace WCell.RealmServer.Gossips
{
	public struct GossipTextEntry
	{
		/// <summary>
		/// $N = Character name
		/// </summary>
		public string TextMale, TextFemale;
		public ChatLanguage Language;
		public float Probability;
		public EmoteType Emote1, Emote2, Emote3, Emote4, Emote5, Emote6;
	}

	/// <summary>
	/// The Id is used by the client to find this entry in its cache.
	/// </summary>
	public interface IGossipEntry
	{
		uint GossipId { get; }

		GossipTextEntry[] GossipEntries { get; }
	}

	[DataHolder]
	public class NPCGossipEntry : IDataHolder, IGossipEntry
	{
		public uint GossipId { get; set; }

		private GossipTextEntry[] m_Entries;

		[Persistent(8)]
		public GossipTextEntry[] GossipEntries
		{
			get { return m_Entries; }
			set { m_Entries = value; }
		}

		public uint GetId()
		{
			return GossipId;
		}

		public DataHolderState DataHolderState
		{
			get;
			set;
		}

		public void FinalizeDataHolder()
		{
			if (m_Entries == null)
			{
				ContentHandler.OnInvalidDBData("Entries is null in: " + this);
				return;
			} 
			ArrayUtil.TruncVals(ref m_Entries);
			if (GossipId > 0)
			{
				GossipMgr.NPCTexts[GossipId] = this;
			}
			else
			{
				ContentHandler.OnInvalidDBData("Invalid id: " + this);
			}
		}
		
		public static IEnumerable<NPCGossipEntry> GetAllDataHolders()
		{
			var list = new List<NPCGossipEntry>(GossipMgr.NPCTexts.Count);
			foreach (var text in GossipMgr.NPCTexts.Values)
			{
				if (text is NPCGossipEntry)
				{
					list.Add((NPCGossipEntry)text);
				}
			}
			return list;
		}

		public override string ToString()
		{
			return GetType().Name + " (Id: " + GossipId + ")";
		}
	}

	[DataHolder]
	public class NPCGossipRelation : IDataHolder
	{
		public NPCId NPCId;

		public uint GossipId;

		public uint GetId()
		{
			return (uint)NPCId;
		}

		public DataHolderState DataHolderState
		{
			get;
			set;
		}

		public void FinalizeDataHolder()
		{
			var entry = NPCMgr.GetEntry(NPCId);
			if (entry != null && entry.DefaultGossip == null)
			{
				var menu = new GossipMenu(GossipId);
				GossipMgr.gossipCount++;

				entry.DefaultGossip = menu;

				if ((entry.NPCFlags & (NPCFlags.SpiritHealer)) == 0)
				{
					entry.NPCFlags |= NPCFlags.Gossip;
				}
				else
				{
					entry.NPCFlags ^= NPCFlags.Gossip;
				}
			}
		}
	}
}
